/*
 * interrupts.h
 *
 *  Created on: 2021年3月2日
 *      Author: root
 */


#ifndef __MYOS__HARDWARECOMMUNICATION__INTERRUPTS_H_
#define __MYOS__HARDWARECOMMUNICATION__INTERRUPTS_H_

#include <hardwarecommunication/port.h>
#include <multitasking.h>
# include <common/types.h>
# include <gdt.h>
#include <memorymanagement.h>

namespace myos{
	namespace hardwarecommunication{

		class InterruptManager;

		// interrupt handler 中断处理程序
		class InterruptHandler
		{
		protected:
			myos::common::uint8_t interruptNumber;
			InterruptManager *interruptManager;

			InterruptHandler(myos::common::uint8_t interruptNumber,InterruptManager *interruptManager);
			~InterruptHandler();
		public:
			virtual myos::common::uint32_t HandleInterrupt(myos::common::uint32_t esp);
		};

		class InterruptManager
		{
			friend class InterruptHandler;  //C++中的friend关键字其实做这样的事情：在一个类中指明其他的类（或者）函数能够直接访问该类中的private和protected成员。
			//IDT
		protected:
			static InterruptManager* ActiveInterruptManager;   //静态变量，指向中断管理

			InterruptHandler* handlers[256];
			myos::common::uint16_t hardwareInterruptOffeset;
			TaskManager *taskManager;

			struct GateDescriptor
			{
				myos::common::uint16_t handlerAddressLowBits;			//处理程序地址低位
				myos::common::uint16_t gdt_codeSefmentSelector;
				myos::common::uint8_t reserved;						//保留字节
				myos::common::uint8_t access;							//访问权限
				myos::common::uint16_t handlerAddressHighBits;
			}__attribute__((packed));         			//最小完整对齐直接取最短

			static GateDescriptor interruptDescriptorTable[256];

			struct InterruptDescriptorTablePointer
			{
				myos::common::uint16_t size;
				myos::common::uint32_t base;
			}__attribute__((packed));


			static void SetInterruptDescriptorTableEntry
			(
				myos::common::uint8_t interruptNumber,
				myos::common::uint16_t codeSegmentSelectorOffset,
				void (*handler)(),
				myos::common::uint8_t DescriptorPrivilegeLevel,
				myos::common::uint8_t DescriptorType
			);

			Port8BitSlow picMasterCommand;
			Port8BitSlow picMasterData;
			Port8BitSlow picSlaveCommand;
			Port8BitSlow picSlaveData;


		public:
			InterruptManager(myos::common::uint16_t hardwareInterruptOffeset,GlobalDescriptorTable *gdt,myos::TaskManager* taskManager);
			~InterruptManager();

			void Activate();
			void Deactivate();
			static myos::common::uint32_t handleInterrupt(myos::common::uint8_t interruptNumber,myos::common::uint32_t esp); //中断编号和当前的堆栈指针
			myos::common::uint32_t DoHandleInterrupt(myos::common::uint8_t interruptNumber,myos::common::uint32_t esp);
			static void IgnoreInterruptRequest();
			static void HandleInterruptRequest0x00();
			static void HandleInterruptRequest0x01();   //timer interrupt
			static void HandleInterruptRequest0x0C();

		};

	}
}


#endif /* __MYOS__HARDWARECOMMUNICATION__INTERRUPTS_H_ */
